15. 单例和网络

单例

唯一的实例,即整个 java 系统中某个类型的对象只有唯一的一个。

无论是饿汉式还是懒汉式的单例,写法都有以下步骤:

  1. 类的构造器私有化(保证使用者不能随意创建第二个对象)
  2. 唯一的实例必须在本类中创建,并且要用一个静态的变量来存储。

饿汉式

无论使用者是否要用这个对象,都会先创建这个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.itguigu.singleton;

public class TestHungry {
public static void main(String[] args) {
// 获取单例对象
Hungry instance = Hungry.instance;

Hungry2 instance2 = Hungry2.instance;

Hungry3 instance3 = Hungry3.getInstance();
}
}

// 饿汉式,创建方式1
class Hungry{
// 2. 用一个静态的变量来存储这个唯一的对象,这个对象是在类初始化时就创建了
public static final Hungry instance = new Hungry();

// 1. 构造器私有外
private Hungry() {

}
}

// 饿汉式,创建方式2
// 利用枚举类的构造方法本身就是私有的,且元素是常量对象
enum Hungry2{
instance
}

//饿汉式,创建方式3
class Hungry3{
// 将创建私有话对象方式隐藏
private static final Hungry3 instance = new Hungry3();

// 构造器私有外
private Hungry3() {

}

// 提供获取实例方法
public static Hungry3 getInstance() {
return instance;
}
}

懒汉式

只有在使用者在来获取这个对象时,才会创建对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.itguigu.singleton;


public class TestLazy {
Lazy instance = Lazy.getInstance();

Lazy2 instance2 = Lazy2.getInstance();

Lazy3 instance3 = Lazy3.getInstance();
}

// 懒汉式,创建方式1
class Lazy{
// 用一个静态变量来保存这个唯一的实例,但是不能 new 对象
private static Lazy instance;

// 私有构造
private Lazy() {

}

// 创建一个获取 instance 的方法,但是考虑到线程安全的问题,所以这里需要加上锁
public synchronized static Lazy getInstance() {
if(instance==null) {
instance = new Lazy();
}
return instance;
}
}

//懒汉式,创建方式1优化,上面方法写法虽然可以达到目的,但是效率不高。以下为在方式1的基础上改进
class Lazy2{
// 用一个静态变量来保存这个唯一的实例,但是不能 new 对象
private static Lazy2 instance;

// 私有构造
private Lazy2() {

}

// 创建一个获取 instance 的方法,但是考虑到线程安全的问题,所以这里需要加上锁
public synchronized static Lazy2 getInstance() {
if (instance==null) { // 外面的这个判断是为了提高效率,当这个对象已经创建过了,那么后面的线程就没有必须等待锁
synchronized (Lazy2.class) {
if(instance==null) { // 里面的判断是为了线程安全
instance = new Lazy2();
}
}
}
return instance;
}
}

//懒汉式,创建方式2,不用考虑线程安全
class Lazy3{
// 私有构造
private Lazy3() {

}

// 内部类
private static class Inner{
// 用一个静态内部类的静态变量来保存这个唯一的对象
private static final Lazy3 instance = new Lazy3();
}

public static Lazy3 getInstance() {
return Inner.instance;
}
}

网络概述

InetAddress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.itguigu.singleton;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.junit.Test;

public class TestInetAddress {
@Test
public void name() throws UnknownHostException {
// 获取本机 host 信息
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
// 获取 HostName
String hostName = localHost.getHostName();
// 获取 HostAddress
String hostAddress = localHost.getHostAddress();
System.out.println("名称:" + hostName + "地址:" + hostAddress);
}

@Test
public void name1() throws UnknownHostException {
// 根据域名查询 IP
InetAddress byName = InetAddress.getByName("www.baidu.com");
System.out.println(byName);
}
}